package com.tools.common.object;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.JsonNode;
import com.tools.common.container.*;
import com.tools.common.exception.IORuntimeException;
import com.tools.common.exception.InvalidOperationException;
import com.tools.common.exception.ParseRuntimeException;
import com.tools.common.object.string.StrKit;
import com.tools.common.object.string.VerifyKit;
import com.tools.common.object.type.handler.ListTypeHandler;
import com.tools.common.object.type.handler.MapTypeHandler;
import com.tools.common.object.type.handler.PairTypeHandler;
import com.tools.common.object.json.JsonKit;
import com.tools.common.object.type.handler.SetTypeHandler;
import com.tools.db.jdbc.JdbcKit;
import com.tools.web.work.excel.poi.*;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;

import javax.servlet.http.HttpServletRequest;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Parameter;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.*;

/**
 * 反射、键值对集合、Map、Bean 对象
 * 等等操作的工具类，同时含有转换值、
 * JSON 反序列化等等操作
 * */
@Note("反射、键值对集合、Map、Bean 对象" +
        "等等操作的工具类，同时含有转换值" +
        "JSON 反序列化等等操作")
public final class ObjKit extends PairsKit {

    private ObjKit() {}



    /* ************************************************************************************************************
     *
     *
     *          非常规构建对象的方法
     *
     * ************************************************************************************************************
     * */


    @Note("根据 targetType 构建目标 JavaBean 对象，然后将 Map 集合里所有与其属性同名的 key 对应的 value 复制过来")
    public static <T>T buildObject(C<T> targetType, Map dataMap) {
        T bean;
        if(targetType.argCount() == 0) {
            bean = buildObject(targetType);
        }
        else {
            Constructor<T> constructor = getConstructor(targetType);
            Object[] values = private_getArgValuesByMap(constructor, targetType, dataMap);
            bean = buildObject(constructor, values);
        }
        if(dataMap == null || dataMap.isEmpty()) return bean;
        Map<String, Field> beanFieldMap = allFields(targetType.getMainType());
        for(Map.Entry<String, Field> e : beanFieldMap.entrySet()) {
            Object value = dataMap.get(e.getKey());
            if(value != null) {
                Field field = e.getValue();
                C<?> fieldTypeC = C.getC(field.getType());
                fieldTypeC.setDateFormatPattern(targetType.getDateFormatPattern());
                Object realValue = toRealValue(value, fieldTypeC);
                setFieldValue(bean, field, realValue);
            }
        }
        return bean;
    }



    @Note("根据 targetType 构建目标 JavaBean 对象，然后将自定义键值对容器里所有与其属性同名的 key 对应的 value 复制过来")
    public static <T>T buildObject(C<T> targetType, OwnPairs dataPair) {
        T bean;
        if(targetType.argCount() == 0) {
            bean = buildObject(targetType.getMainType());
        }
        else {
            Constructor<T> constructor = getConstructor(targetType);
            Object[] values = private_getArgValuesByPair(constructor, targetType,  dataPair);
            bean = buildObject(constructor, values);
        }
        if(dataPair == null || dataPair.isEmpty()) return bean;
        Map<String, Field> beanFieldMap = allFields(targetType.getMainType());
        for(Map.Entry<String, Field> e : beanFieldMap.entrySet()) {
            Object value = dataPair.get(e.getKey());
            if(value == null) {
                continue;
            }
            Field field = e.getValue();
            C<?> fieldTypeC = C.getC(field.getType());
            fieldTypeC.setDateFormatPattern(targetType.getDateFormatPattern());
            Object realValue = toRealValue(value, fieldTypeC);
            setFieldValue(bean, field, realValue);
        }
        return bean;
    }


    @Note("根据 targetType 构建目标 JavaBean 对象，然后将 JSON 字符串实例里所有与其属性同名的 key 对应的 value 复制过来")
    public static <T>T buildObject(C<T> targetType, JsonNode jsonNode) {
        T bean;
        if(targetType.argCount() == 0) {
            bean = buildObject(targetType.getMainType());
        }
        else {
            Constructor<T> constructor = getConstructor(targetType);
            Object[] values = private_getArgValuesByJsonNode(constructor, targetType, jsonNode);
            bean = buildObject(constructor, values);
        }
        if(jsonNode == null || jsonNode.isEmpty()) return bean;
        Map<String, Field> fieldMap = allFields(targetType.getMainType());
        Iterator<Map.Entry<String, JsonNode>> jsonNodeFields = jsonNode.fields();
        while (jsonNodeFields.hasNext()) {
            Map.Entry<String, JsonNode> e = jsonNodeFields.next();
            Field field = fieldMap.get(e.getKey());
            if(field == null) continue;
            C<?> fieldTypeC = C.getC(field.getType());
            fieldTypeC.setDateFormatPattern(targetType.getDateFormatPattern());
            Object realValue = jsonNodeToRealValue(e.getValue(), fieldTypeC);
            setFieldValue(bean, field, realValue);
        }
        return bean;
    }


    @Note("根据 targetType 构建目标 JavaBean 对象，然后将 JSON 字符串实例里所有与其属性同名的 key 对应的 value 复制过来")
    public static <T> T buildObject(C<T> targetType, JsonParser parser) {
        T bean;
        if(targetType.argCount() == 0) {
            bean = buildObject(targetType.getMainType());
        }
        else {
            JsonNode jsonNode = JsonKit.readToNode(parser);
            return buildObject(targetType, jsonNode);
        }
        if(parser == null) return bean;
        Map<String, Field> fieldMap = allFields(targetType.getMainType());
        try {
            while (parser.nextToken() != JsonToken.END_OBJECT) {
                if (parser.currentToken() == JsonToken.FIELD_NAME) {
                    String fieldName = parser.getCurrentName();
                    parser.nextToken();
                    Field field = fieldMap.get(fieldName);
                    if(field == null) continue;
                    C<?> fieldTypeC = C.getC(field.getType());
                    Object srcValue = JsonKit.parseToken(parser, fieldTypeC);
                    Object value = ObjKit.toRealValue(srcValue, fieldTypeC);
                    setFieldValue(bean, field, value);
                }
            }
            return bean;
        } catch (IOException e) {
            throw new IORuntimeException(e);
        }
    }


    @Note("根据 targetType 构建目标 JavaBean 对象，然后将 src 对象里与 target 对象同名的属性的值复制过去")
    public static <T>T buildObject(C<T> targetType, Object srcBean) {
        Class<T> mainType = targetType.getMainType();
        int argCount = targetType.argCount();
        if(srcBean == null) {
            return private_beanIsEmptyBuild(argCount, mainType, targetType);
        }
        Map<String, Field> srcFieldMap = allFields(srcBean.getClass());
        if(srcFieldMap.isEmpty()) {
            return private_beanIsEmptyBuild(argCount, mainType, targetType);
        }
        T bean;
        if(argCount == 0) {
            bean = buildObject(mainType);
        }
        else {
            Constructor<T> constructor = getConstructor(targetType);
            Object[] argValues = private_getArgValuesByBean(targetType, srcFieldMap, srcBean, constructor, argCount);
            bean = buildObject(constructor, argValues);
        }
        Map<String, Field> beanFieldMap = allFields(targetType.getMainType());
        for(Map.Entry<String, Field> e : beanFieldMap.entrySet()) {
            String beanKey = e.getKey();
            Field srcField = srcFieldMap.get(beanKey);
            if(srcField == null) {
                continue;
            }
            Object srcValue = getFieldValue(srcBean, srcField);
            Field beanField = e.getValue();
            C<?> fieldTypeC = C.getC(beanField.getType());
            fieldTypeC.setDateFormatPattern(targetType.getDateFormatPattern());
            Object realValue = toRealValue(srcValue, fieldTypeC);
            setFieldValue(bean, beanField, realValue);
        }
        return bean;
    }



    @Note("根据 targetType 构建目标 JavaBean 对象，然后将 HttpServletRequest 请求对象里所有与其属性同名的请求参数名称的 value 复制过来")
    public static <T>T buildObject(C<T> targetType, HttpServletRequest request) {
        T bean;
        Map<String, String[]> parameterMap = request.getParameterMap();
        if(targetType.argCount() == 0) {
            bean = buildObject(targetType.getMainType());
        } else {
            Constructor<T> constructor = getConstructor(targetType);
            Object[] values = private_getArgValuesByRequestParameters(constructor, targetType, parameterMap);
            bean = buildObject(constructor, values);
        }
        Map<String, Field> fieldMap = allFields(targetType.getMainType());
        for (Map.Entry<String, Field> e : fieldMap.entrySet()) {
            String[] a = parameterMap.get(e.getKey());
            if(a == null) continue;
            Field field = e.getValue();
            Object value = private_stringArrayToRealValue(a, C.getC(field.getType()));
            ObjKit.setFieldValue(bean, field, value);
        }
        return bean;
    }


    @Note("根据 targetType 构建目标 JavaBean 对象，然后将结果集里与对象属性名称相同的字段的值 set 进 JavaBean 对象里")
    public static <T>T buildObject(C<T> targetType, ResultSet resultSet, ResultSetMetaData metaData, int columnCount) {
        T bean;
        if(targetType.argCount() == 0) {
            bean = buildObject(targetType.getMainType());
        } else {
            Constructor<T> constructor = getConstructor(targetType);
            Object[] values = private_getArgValuesByResultSet(constructor, targetType, resultSet);
            bean = buildObject(constructor, values);
        }
        Map<String, Field> fieldMap = allFields(targetType.getMainType());
        for (int i = 0; i < columnCount; i++) {
            int index = i + 1;
            String columnName = JdbcKit.getColumnNameByIndex(metaData, index);
            String fieldName = StrKit.toProperty(columnName);
            Field field = fieldMap.get(fieldName);
            if(field != null) {
                Object o = JdbcKit.getResultValueByColumnIndex(resultSet, index);
                Object realValue = toRealValue(o, C.getC(field.getType()));
                setFieldValue(bean, field, realValue);
            }
        }
        return bean;
    }


    @Note("根据 targetType 构建目标 JavaBean 对象，然后将 Row 里与对象属性名称相同的单元格值 set 进 JavaBean 对象里")
    public static <T>T buildObject(Row row, SheetImporter sheetImporter,
                                   ExcelImporter excelImporter, C<T> targetType) {
        T bean;
        if(targetType.argCount() == 0) {
            bean = buildObject(targetType.getMainType());
        } else {
            Constructor<T> constructor = getConstructor(targetType);
            Object[] values = private_getArgValuesByExcelRow(constructor, targetType,
                    row, excelImporter, sheetImporter);
            bean = buildObject(constructor, values);
        }
        Map<String, Field> fieldMap = allFields(targetType.getMainType());
        ExcelHead excelHead = sheetImporter.getExcelHead();
        for (int j = 0; j < row.getLastCellNum(); j++) {
            ExcelField excelField = excelHead.get(j);
            if(excelField == null) {
                throw new IndexOutOfBoundsException(j + " 索引出错，无法获取到当前列配置");
            }
            String fieldName = excelField.getField();
            if(sheetImporter.hasIgField(fieldName)) {
                continue;
            }
            Field field = fieldMap.get(fieldName);
            Class<?> fieldType = field.getType();
            if(ExcelKit.isImageType(fieldType)) {
                continue;
            }
            Cell cell = row.getCell(j);
            String cellValue = (cell == null) ? null : cell.toString();
            try {
                Object value = stringToRealValue(cellValue, C.getC(fieldType));
                setFieldValue(bean, field, value);
            } catch (Exception e) {
                String message = "值转换出错，或者赋值出错。[" + fieldName + ", " + fieldType.getName() + ", " + cellValue + "], => " + e.getMessage();
                excelImporter.addError(row, j, message);
            }
        }
        return bean;
    }

    /* ************************************************************************************************************
     *
     *          字符串与其他类型的互相转换操作
     *
     * ************************************************************************************************************
     * */

    @Note("将目标 JavaBean 对象转为字符串输出，如果对象为 null 则转换的字符串也为 null")
    public static String toStringNullValue(Object value) {
        return toStringValue(value, null, true);
    }

    @Note("将目标 JavaBean 对象转为字符串输出，如果对象为 null 则转换的字符串由空字符串替代")
    public static String toStringEmptyString(Object value) {
        return toStringValue(value, "", true);
    }

    @Note("将目标 JavaBean 对象转为字符串输出，如果对象为 null 则转换的字符串由 ”null“ 字符串替代")
    public static String toStringNullString(Object value) {
        return toStringValue(value, "null", true);
    }

    @Note("将目标 JavaBean 对象转为字符串输出")
    public static String toStringValue(Object value, String nullDefaultValue, boolean isToJSON) {
        if(value == null) {
            return nullDefaultValue;
        }
        if(
                value instanceof CharSequence ||
                        value instanceof Number ||
                        value instanceof Boolean ||
                        value instanceof Character ||
                        value instanceof Enum
        ) {
            return value.toString();
        }
        if(value instanceof File) {
            return ((File) value).getAbsolutePath();
        }
        if(isToJSON) {
            return JsonKit.toJSON(value);
        }
        return StrKit.toString(value);
    }


    @Note("将 sourceValue 做字符串输出，如果 sourceValue 为 null 则用 isNullDefaultValue 替代")
    public static String asStringValue(Object sourceValue, String isNullDefaultValue) {
        return (sourceValue == null) ? isNullDefaultValue : sourceValue.toString();
    }


    @Note("将 sourceValue 做字符串输出，如果 sourceValue 为 null 则用 nullDefaultValue 替代")
    public static Object asValue(Object sourceValue, Object isNullDefaultValue) {
        return (sourceValue == null) ? isNullDefaultValue : sourceValue;
    }

    @Note("字符串转为布尔值")
    public static Boolean stringToBoolean(String value) {
        if("true".equalsIgnoreCase(value)) return true;
        if("false".equalsIgnoreCase(value)) return false;
        return null;
    }


    @Note("将字符串转为整数")
    public static Number stringToWholeNumber(String value) {
        if(VerifyKit.isFloat(value)) {
            value = value.substring(0, value.indexOf("."));
            if(value.isEmpty()) return 0;
        }
        int length = value.length();
        if(length <= 10) {
            try{
                return Integer.parseInt(value);
            } catch (Exception e) {
                return Long.parseLong(value);
            }
        }
        if(length <= 19) {
            try{
                return Long.parseLong(value);
            } catch (Exception e) {
                return new BigInteger(value);
            }
        }
        return new BigInteger(value);
    }

    @Note("如果 value 返回 double 不丢失精度就返回 double，否则就返回 BigDecimal")
    public static Number stringToFloatNumber(String value) {
        if(value == null || value.isEmpty()) return null;
        if(!value.contains(".")) {
            value = value + ".0";
        }
        String[] parts = value.split("\\.");
        if(parts.length >= 2) {
            String intPart = parts[0];
            String decPart = parts[1];
            if(decPart.isEmpty()) return 0.0;
            if (intPart.length() + decPart.length() > 17) {
                return new BigDecimal(value);
            }
            return Double.parseDouble(value);
        }
        if(value.length() > 16) {
            return new BigDecimal(value);
        }
        return Double.parseDouble(value);
    }


    @Note("将目标字符串尽可能转为正确的对象")
    public static Object stringToRealValue(String value) {
        return stringToRealValue(value, true);
    }

    @Note("将目标字符串尽可能转为正确的对象。" +
            "jsonIsCast 可以设置如果 value 为 JSON 是否要反序列化为对象。" +
            "对象类型反序列化为 LinkedHashMap，数组类型反序列化为 ArrayList")
    public static Object stringToRealValue(String value, boolean jsonIsCast) {
        if(value == null) return null;
        if(VerifyKit.isJsonString(value)) {
            return jsonIsCast ? JsonKit.toEntity(value) : value;
        }
        if(value.length() == 1) {
            char c = value.charAt(0);
            if(c >= 48 && c <= 57) return Integer.parseInt(value);
            return value;
        }
        if(VerifyKit.isWholeNumber(value)) {
            return stringToWholeNumber(value);
        }
        if(VerifyKit.isBoolean(value)) {
            return Boolean.parseBoolean(value);
        }
        if(VerifyKit.isFloat(value)) {
            return stringToFloatNumber(value);
        }
        return value;
    }


    @Note("将目标字符串转为目标对应的 targetType 对应的 Java 对象")
    public static Object stringToRealValue(String value, C<?> targetType) {
        if(value == null) return null;
        if(targetType == null) return stringToRealValue(value, true);
        Class<?> targetClass = targetType.getMainType();
        if(String.class.equals(targetClass)) {
            return value;
        }
        if(Object.class.equals(targetClass)) {
            return stringToRealValue(value, true);
        }
        Object realValue = BasicEnum.matchAndGetValue(value, targetClass);
        if(realValue != null) {
            return realValue;
        }
        if(DateKit.isDateClass(targetClass)) {
            return DateKit.toDateEntity(value, targetClass, targetType.getDateFormatPattern());
        }
        if(Enum.class.isAssignableFrom(targetClass)) {
            return buildEnum(targetClass, value);
        }
        if(VerifyKit.isJsonString(value)) {
            return JsonKit.toEntity(value, targetType);
        }
        if(File.class.isAssignableFrom(targetClass)) {
            return new File(value);
        }
        throw new ClassCastException("无法将 【" + value.getClass().getName() + "】 转化为 " +
                "【" + targetClass.getName() + "】 类型数据");
    }


    /* ************************************************************************************************************
     *
     *          其他类型的互相转换操作
     *
     * ************************************************************************************************************
     * */


    @Note("将源值用尽办法尽可能地转化为目标类型的新值")
    public static Object toRealValue(Object source, C<?> targetType) {
        if(targetType == null) return source;
        Class<?> targetClass = targetType.getMainType();
        //判断 source 为 null 则看看目标类型是不是基本类型，是则返回默认值
        if(source == null) {
            return BasicEnum.getDefaultValue(targetClass);
        }
        //target 是父类，则直接返回 source
        if(targetClass.isAssignableFrom(source.getClass())) return source;
        //如果 target 是字符串，则直接调用 toStringValue 方法转换
        if(String.class.equals(targetClass)) return toStringNullValue(source);
        //如果 target 类型是基本类型或者其包装类
        Object realValue = BasicEnum.matchAndGetValue(source, targetClass);
        if(realValue != null) {
            return realValue;
        }
        //如果源值 source 是字符串，则直接调用 stringToRealValue 方法转换
        if(source instanceof String) return stringToRealValue((String) source, targetType);
        //如果是日期时间类型
        if(DateKit.isDateClass(targetClass)) {
            return DateKit.toDateEntity(source, targetClass, targetType.getDateFormatPattern());
        }
        //如果是枚举类型
        if(Enum.class.isAssignableFrom(targetClass)) {
            return buildEnum(targetClass, source.toString());
        }
        //如果是 Json 类型的对象，则
        if(source instanceof JsonParser) {
            try(JsonParser parser = (JsonParser) source) {
                return jsonParserToRealValue(parser, targetType);
            } catch (Exception e) {
                throw new ParseRuntimeException(e);
            }
        }
        if(source instanceof JsonNode) {
            return jsonNodeToRealValue((JsonNode) source, targetType);
        }
        //如果 source 是 Map 集合
        if(source instanceof Map) {
            Map map = (Map) source;
            if(Map.class.isAssignableFrom(targetClass)) {
                return MapTypeHandler.castToMap(map, targetType);
            }
            if(OwnPairs.class.isAssignableFrom(targetClass)) {
                return PairTypeHandler.castToOwnPairs(map, targetType);
            }
            return buildObject(targetType, map);
        }
        //如果 source 是自定义键值对容器
        if(source instanceof OwnPairs) {
            OwnPairs pair = (OwnPairs) source;
            if(OwnPairs.class.isAssignableFrom(targetClass)) {
                return PairTypeHandler.castToOwnPairs(pair, targetType);
            }
            if(Map.class.isAssignableFrom(targetClass)) {
                return MapTypeHandler.castToMap(pair, targetType);
            }
            return buildObject(targetType, pair);
        }
        //如果 source 是 Collection 集合
        if(source instanceof Collection) {
            Collection cs = (Collection) source;
            if(Collection.class.equals(targetClass) || List.class.isAssignableFrom(targetClass)) {
                return ListTypeHandler.castToList(cs, targetType);
            }
            if(Set.class.isAssignableFrom(targetClass)) {
                return SetTypeHandler.castToSet(cs, targetType);
            }
            if(OwnRows.class.equals(targetClass) || AbsOwnList.class.isAssignableFrom(targetClass)) {
                return ListTypeHandler.castToAbsOwnList(cs, targetType);
            }
            if(AbsOwnSet.class.isAssignableFrom(targetClass)) {
                return SetTypeHandler.castToAbsOwnSet(cs, targetType);
            }
            if(targetClass.isArray()) {
                return RowKit.buildArray(targetType, cs);
            }
            throw new ClassCastException("无法将 【" + source.getClass().getName() + "】 " +
                    "转换为 【" + targetClass.getName() + "】");
        }
        //如果 source 是自定义容器
        if(source instanceof OwnRows) {
            OwnRows row = (OwnRows) source;
            if(OwnRows.class.equals(targetClass) || AbsOwnList.class.isAssignableFrom(targetClass)) {
                return ListTypeHandler.castToAbsOwnList(row, targetType);
            }
            if(AbsOwnSet.class.isAssignableFrom(targetClass)) {
                return SetTypeHandler.castToAbsOwnSet(row, targetType);
            }
            if(Collection.class.equals(targetClass) || List.class.isAssignableFrom(targetClass)) {
                return ListTypeHandler.castToList(row, targetType);
            }
            if(Set.class.isAssignableFrom(targetClass)) {
                return SetTypeHandler.castToSet(row, targetType);
            }
            if(targetClass.isArray()) {
                return RowKit.buildArray(targetType, row);
            }
            throw new ClassCastException("无法将 【" + source.getClass().getName() + "】 " +
                    "转换为 【" + targetClass.getName() + "】");
        }
        //如果 source 是数组
        if(source.getClass().isArray()) {
            if(targetClass.isArray()) {
                return RowKit.buildArray(targetType, source);
            }
            if(Set.class.isAssignableFrom(targetClass)) {
                return SetTypeHandler.castToSet(source, targetType);
            }
            if(Collection.class.equals(targetClass) || List.class.isAssignableFrom(targetClass)) {
                return ListTypeHandler.castToList(source, targetType);
            }
            if(OwnRows.class.equals(targetClass) || AbsOwnList.class.isAssignableFrom(targetClass)) {
                return ListTypeHandler.castToAbsOwnList(source, targetType);
            }
            if(AbsOwnSet.class.isAssignableFrom(targetClass)) {
                return SetTypeHandler.castToAbsOwnSet(source, targetType);
            }
            throw new ClassCastException("无法将数组 【" + source.getClass().getName() + "】 " +
                    "转换为 【" + targetClass.getName() + "】");
        }
        //都不是，那就将 source 按普通 JavaBean 对象处理
        if(Map.class.isAssignableFrom(targetClass)) {
            return MapTypeHandler.castToMap(source, targetType);
        }
        if(OwnPairs.class.isAssignableFrom(targetClass)) {
            return PairTypeHandler.castToOwnPairs(source, targetType);
        }
        return buildObject(targetType, source);
    }



    @Note("将 JSON 字符串实例 JsonNode 转为 JavaBean 对象")
    public static Object jsonNodeToRealValue(JsonNode valueNode, C<?> targetType) {
        if(valueNode == null) return null;
        String value = valueNode.toString();
        if(targetType == null) return value;
        Class<?> targetClass = targetType.getMainType();
        int size = valueNode.size();
        if(value.startsWith("{") && value.endsWith("}")) {
            if(Map.class.isAssignableFrom(targetClass)) {
                Map map = MapEnum.buildMap(targetType, size);
                Iterator<Map.Entry<String, JsonNode>> fields = valueNode.fields();
                C<?> keyType = targetType.genericSafe(0);
                C<?> valueType = targetType.genericSafe(1);
                while (fields.hasNext()) {
                    Map.Entry<String, JsonNode> e = fields.next();
                    map.put(toRealValue(e.getKey(), keyType), jsonNodeToRealValue(e.getValue(), valueType));
                }
                return map;
            }
            if(OwnPairs.class.isAssignableFrom(targetClass)) {
                OwnPairs pair = MapEnum.buildPair(targetType, size);
                Iterator<Map.Entry<String, JsonNode>> fields = valueNode.fields();
                C<?> valueType = targetType.genericSafe(1);
                C<?> keyType = targetType.genericSafe(0);
                while (fields.hasNext()) {
                    Map.Entry<String, JsonNode> e = fields.next();
                    pair.put(toRealValue(e.getKey(), keyType), jsonNodeToRealValue(e.getValue(), valueType));
                }
                return pair;
            }
            return buildObject(targetType, valueNode);
        }
        if(value.startsWith("[") && value.endsWith("]")) {
            Iterator<JsonNode> elements = valueNode.elements();
            C<?> componentType = targetType.genericSafe(0);
            if(Collection.class.equals(targetClass) || List.class.isAssignableFrom(targetClass)) {
                List list = ListEnum.buildList(targetType, size);
                while (elements.hasNext()) {
                    list.add(jsonNodeToRealValue(elements.next(), componentType));
                }
                return list;
            }
            if(Set.class.isAssignableFrom(targetClass)) {
                Set set = SetEnum.buildSet(targetType, size);
                while (elements.hasNext()) {
                    set.add(jsonNodeToRealValue(elements.next(), componentType));
                }
                return set;
            }
            if(OwnRows.class.isAssignableFrom(targetClass)) {
                OwnRows row = RowKit.buildRow(targetType, size);
                while (elements.hasNext()) {
                    row.add(jsonNodeToRealValue(elements.next(), componentType));
                }
                return row;
            }
            if(targetClass.isArray()) {
                Object array = RowKit.buildArray(targetType, size);
                int index = 0;
                while (elements.hasNext()) {
                    if(index == size) return array;
                    Array.set(array, index, jsonNodeToRealValue(elements.next(), componentType));
                    index++;
                }
            }
            throw new ClassCastException("无法将 【" + value + "】 " +
                    "转换为 【" + targetClass.getName() + "】");
        }
        return stringToRealValue(valueNode.toString(), targetType);
    }


    @Note("将 JSON 字符串解析器流 JsonParser 转为 JavaBean 对象")
    public static Object jsonParserToRealValue(String json, C<?> targetType) {
        JsonParser parser = null;
        try {
            parser = JsonKit.newJsonParser(json);
            return jsonParserToRealValue(parser, targetType);
        } catch (Exception e) {
            throw new ParseRuntimeException(e);
        } finally {
            JsonKit.close(parser);
        }
    }


    @Note("将 JSON 字符串解析器流 JsonParser 转为 JavaBean 对象")
    public static Object jsonParserToRealValue(JsonParser parser, C<?> targetType) {
        if(parser == null || targetType == null) return null;
        try {
            if(parser.currentToken() == null) {
                parser.nextToken();
            }
            return JsonKit.parseToken(parser, targetType);
        } catch (Exception e) {
            throw new ParseRuntimeException(e);
        }
    }



    /* ************************************************************************************************************
     *
     *
     *          复制操作
     *
     * ************************************************************************************************************
     * */


    @Note("将 source 源对象的所有内容拷贝至 target 内")
    public static void copy(Object source, Object target) {
        if(source == null || target == null) return;
        if(private_containerCopy(source, target)) {
            return;
        }
        private_beanCopy(allFields(source.getClass()), allFields(target.getClass()), source, target);
    }


    @Note("将 source 源对象的所有内容拷贝至 target 内" +
            "但此拷贝操作会排除掉与 excludePropertyNames 数组里重名的那些 key 或属性")
    public static void copy(Object source, Object target, String... excludePropertyNames) {
        if(source == null || target == null) return;
        if(private_containerCopy(source, target)) {
            if(excludePropertyNames == null || excludePropertyNames.length == 0) return;
            private_containerExcludesOperation(target, excludePropertyNames);
            return;
        }
        Map<String, Field> sourceMap = allFields(source.getClass());
        Map<String, Field> targetMap = allFields(target.getClass());
        if(excludePropertyNames != null && excludePropertyNames.length != 0) {
            for (String property : excludePropertyNames) targetMap.remove(property);
        }
        private_beanCopy(sourceMap, targetMap, source, target);
    }


    @Note("将 source 源对象的所有内容拷贝至 target 内" +
            "但此拷贝操作会排除掉与 excludePropertyNames 可迭代容器里重名的那些 key 或属性")
    public static void copy(Object source, Object target, Iterable<String> excludePropertyNames) {
        if(source == null || target == null) return;
        if(private_containerCopy(source, target)) {
            if(excludePropertyNames == null || !excludePropertyNames.iterator().hasNext()) return;
            private_containerExcludesOperation(target, excludePropertyNames);
            return;
        }
        Map<String, Field> sourceMap = allFields(source.getClass());
        Map<String, Field> targetMap = allFields(target.getClass());
        if(excludePropertyNames != null) {
            for (String property : excludePropertyNames) targetMap.remove(property);
        }
        private_beanCopy(sourceMap, targetMap, source, target);
    }


    /* ************************************************************************************************************
     *
     *
     *          私有逻辑
     *
     * ************************************************************************************************************
     * */

    @Note("判断 C.TV 形参包装对象在创建时是否传入实参，然后做相应的处理，将实参值保存在 values 数组里返回")
    private static boolean private_ifHasValueSet(C.TV tv, int index, Object[] values) {
        if(tv.hasValue()) {
            values[index] = tv.getValue();
            tv = null;
            return true;
        }
        return false;
    }

    @Note("根据构造器的形参名称，在 JsonNode 实例中找到对应的值，并尽可能转为形参类型对应的值，从而让构造器完成 Bean 实例的构造")
    private static Object[] private_getArgValuesByJsonNode(Constructor<?> constructor, C<?> targetType, JsonNode jsonNode) {
        Parameter[] parameters = constructor.getParameters();
        Object[] values = new Object[parameters.length];
        if(jsonNode == null || jsonNode.isEmpty()) {
            return private_dataContainerIsEmpty(values, parameters.length, targetType);
        }
        for (int i = 0; i < parameters.length; i++) {
            C.TV tv = targetType.get(i);
            if(private_ifHasValueSet(tv, i, values)) {
                continue;
            }
            Class<?> type = parameters[i].getType();
            String name = parameters[i].getName();
            JsonNode val = jsonNode.get(name);
            if(val != null) {
                C<?> c = C.getC(type);
                c.setDateFormatPattern(targetType.getDateFormatPattern());
                values[i] = jsonNodeToRealValue(val, c);
                continue;
            }
            values[i] = tv.getOrDefaultValue();
        }
        return values;
    }


    @Note("根据构造器的形参名称，在 Map 集合中找到对应的值，并尽可能转为形参类型对应的值，从而让构造器完成 Bean 实例的构造")
    private static Object[] private_getArgValuesByMap(Constructor<?> constructor, C<?> targetType, Map dataMap) {
        Parameter[] parameters = constructor.getParameters();
        Object[] values = new Object[parameters.length];
        if(dataMap != null && dataMap.isEmpty()) {
            return private_dataContainerIsEmpty(values, parameters.length, targetType);
        }
        for (int i = 0; i < parameters.length; i++) {
            C.TV tv = targetType.get(i);
            if(private_ifHasValueSet(tv, i, values)) {
                continue;
            }
            Class<?> type = parameters[i].getType();
            String name = parameters[i].getName();
            Object value = dataMap.get(name);
            if(value != null) {
                C<?> c = C.getC(type);
                c.setDateFormatPattern(targetType.getDateFormatPattern());
                values[i] = toRealValue(value, c);
                continue;
            }
            values[i] = tv.getOrDefaultValue();
        }
        return values;
    }

    @Note("根据构造器的形参名称，在 HTTP 请求参数的 Map 集合中找到对应的值，并尽可能转为形参类型对应的值，从而让构造器完成 Bean 实例的构造")
    private static Object[] private_getArgValuesByRequestParameters(Constructor<?> constructor, C<?> targetType, Map<String, String[]> parameterMap) {
        Parameter[] parameters = constructor.getParameters();
        Object[] values = new Object[parameters.length];
        for (int i = 0; i < parameters.length; i++) {
            C.TV tv = targetType.get(i);
            if(private_ifHasValueSet(tv, i, values)) {
                continue;
            }
            Class<?> type = parameters[i].getType();
            String name = parameters[i].getName();
            String[] value = parameterMap.get(name);
            if(value != null) {
                C<?> c = C.getC(type);
                c.setDateFormatPattern(targetType.getDateFormatPattern());
                values[i] = private_stringArrayToRealValue(value, c);
                continue;
            }
            values[i] = tv.getOrDefaultValue();
        }
        return values;
    }

    @Note("将请求参数中的字符串数组尽可能将其转为真实的参数值")
    private static Object private_stringArrayToRealValue(String[] array, C<?> type) {
        if(array == null || array.length == 0) return null;
        if(type == null) {
            if(array.length == 1) {
                return ObjKit.stringToRealValue(array[0], true);
            }
            ArrayList<Object> list = new ArrayList<>(array.length);
            for(String value : array) {
                Object realValue = ObjKit.stringToRealValue(value, true);
                list.add(realValue);
            }
            return list;
        }
        if(array.length == 1) {
            return ObjKit.stringToRealValue(array[0], type);
        }
        ArrayList<Object> list = new ArrayList<>(array.length);
        for(String value : array) {
            Object realValue = ObjKit.stringToRealValue(value, type);
            list.add(realValue);
        }
        return list;
    }


    @Note("根据构造器的形参名称，在自定义键值对容器集合中找到对应的值，并尽可能转为形参类型对应的值，从而让构造器完成 Bean 实例的构造")
    private static Object[] private_getArgValuesByPair(Constructor<?> constructor, C<?> targetType, OwnPairs dataPair) {
        Parameter[] parameters = constructor.getParameters();
        Object[] values = new Object[parameters.length];
        if(dataPair != null && !dataPair.isEmpty()) {
            return private_dataContainerIsEmpty(values, parameters.length, targetType);
        }
        for (int i = 0; i < parameters.length; i++) {
            C.TV tv = targetType.get(i);
            if(private_ifHasValueSet(tv, i, values)) {
                continue;
            }
            String name = parameters[i].getName();
            Object value = dataPair.get(name);
            Class<?> type = parameters[i].getType();
            if(value != null) {
                C<?> c = C.getC(type);
                c.setDateFormatPattern(targetType.getDateFormatPattern());
                values[i] = toRealValue(value, c);
                continue;
            }
            values[i] = tv.getOrDefaultValue();
        }
        return values;
    }

    @Note("如果反射构建实体时遇到装载数据的容器为空，则默认使用自带的实参或者默认值")
    private static Object[] private_dataContainerIsEmpty(Object[] values, int length, C<?> targetType) {
        for (int i = 0; i < length; i++) {
            C.TV tv = targetType.get(i);
            if(private_ifHasValueSet(tv, i, values)) {
                continue;
            }
            values[i] = tv.getOrDefaultValue();
        }
        return values;
    }

    @Note("源 Java 实体对象为 null 或者属性为空，那么就使用自带的实参或默认值构造对象")
    private static <T>T private_beanIsEmptyBuild(int argCount, Class<T> mainType, C<T> targetType) {
        if(argCount == 0) {
            return buildObject(mainType);
        }
        Constructor<T> constructor = getConstructor(targetType);
        Parameter[] parameters = constructor.getParameters();
        Object[] argValues = private_dataContainerIsEmpty(new Object[parameters.length], parameters.length, targetType);
        return buildObject(constructor, argValues);
    }

    @Note("根据构造器的形参名称，在 srcBean 对象中找到对应的属性，并将属性值尽可能转为形参类型对应的值，从而让构造器完成目标 Bean 实例的构造")
    private static Object[] private_getArgValuesByBean(C<?> targetType, Map<String, Field> srcFieldMap, Object srcBean, Constructor<?> constructor, int argCount) {
        Object[] values = new Object[argCount];
        Parameter[] parameters = constructor.getParameters();
        for (int i = 0; i < parameters.length; i++) {
            C.TV tv = targetType.get(i);
            if(private_ifHasValueSet(tv, i, values)) {
                continue;
            }
            Class<?> type = parameters[i].getType();
            String name = parameters[i].getName();
            Field field = srcFieldMap.get(name);
            if(field != null) {
                Object value = getFieldValue(srcBean, field);
                C<?> c = C.getC(type);
                c.setDateFormatPattern(targetType.getDateFormatPattern());
                values[i] = toRealValue(value, c);
                continue;
            }
            values[i] = tv.getOrDefaultValue();
        }
        return values;
    }


    @Note("根据构造器的形参名称，在结果集 ResultSet 里找到与之相同的字段的值，并尽可能转为形参类型对应的值，从而让构造器完成 Bean 实例的构造")
    private static Object[] private_getArgValuesByResultSet(Constructor<?> constructor, C<?> targetType, ResultSet resultSet) {
        Parameter[] parameters = constructor.getParameters();
        Object[] argValues = new Object[parameters.length];
        Parameter p;
        for (int i = 0; i < parameters.length; i++) {
            C.TV tv = targetType.get(i);
            if(private_ifHasValueSet(tv, i, argValues)) {
                continue;
            }
            try {
                p = parameters[i];
                Class<?> type = p.getType();
                String name = StrKit.toDBField(p.getName());
                Object value = JdbcKit.getResultValueByColumnName(resultSet, name);
                argValues[i] = toRealValue(value, C.getC(type));
            } catch (Exception e) {
                argValues[i] = tv.getOrDefaultValue();
            }
        }
        return argValues;
    }


    @Note("根据构造器的形参名称，在 Row 对象中找到对应的单元格值，并将值尽可能转为形参类型对应的值，从而让构造器完成目标 Bean 实例的构造")
    private static Object[] private_getArgValuesByExcelRow(Constructor<?> constructor, C<?> targetType,
                                                           Row row, ExcelImporter excelImporter,
                                                           SheetImporter sheetImporter) {
        Parameter[] parameters = constructor.getParameters();
        Object[] argValues = new Object[parameters.length];
        for (int i = 0; i < parameters.length; i++) {
            C.TV tv = targetType.get(i);
            if(private_ifHasValueSet(tv, i, argValues)) {
                continue;
            }
            Parameter p = parameters[i];
            String name = p.getName();
            ExcelHead excelHead = sheetImporter.getExcelHead();
            for (int j = 0; j < excelHead.getHeadCount(); j++) {
                ExcelField excelField = excelHead.get(j);
                if(excelField == null) {
                    continue;
                }
                if(name.equals(excelField.getField())) {
                    Class<?> type = p.getType();
                    if(ExcelKit.isImageType(type)) {
                        argValues[i] = null;
                        continue;
                    }
                    Cell cell = row.getCell(j);
                    String strValue = (cell == null) ? null : cell.toString();
                    try {
                        Object value = stringToRealValue(strValue, C.getC(type));
                        argValues[i] = value;
                    } catch (Exception ex) {
                        String message = "值转换出错，或者赋值出错。[" + name + ", " + type.getName() + ", " + strValue + "], => " + ex.getMessage();
                        excelImporter.addError(row, j, message);
                    }
                    break;
                }
            }
        }
        return argValues;
    }

    @Note("根据 mapType 构建 Map 集合，然后将 srcFieldMap 里的所有属性名称和属性值 put 进去")
    private static Map private_buildMap(C<?> mapType, Map<String, Field> srcFieldMap, Object srcBean) {
        C<?> keyType = mapType.generic(0);
        if(keyType != null && !String.class.equals(keyType.getMainType())) {
            throw new ClassCastException("JavaBean 对象转换为 Map 集合时，Map 集合的 key 的泛型必须是字符串");
        }
        Class<?> mainType = mapType.getMainType();
        int argCount = mapType.argCount();
        Map result;
        if(argCount == 0) {
            result = MapEnum.newMap(mainType, srcFieldMap.size());
        }
        else {
            Constructor<?> constructor = getConstructor(mapType);
            Object[] argValues = private_getArgValuesByBean(mapType, srcFieldMap, srcBean, constructor, argCount);
            result = (Map) buildObject(constructor, argValues);
        }
        C<?> valueType = mapType.generic(1);
        for (Map.Entry<String, Field> e : srcFieldMap.entrySet()) {
            Field field = e.getValue();
            Object value = getFieldValue(srcBean, field);
            Object realValue = toRealValue(value, valueType);
            result.put(e.getKey(), realValue);
        }
        return result;
    }


    @Note("根据 pairType 构建自定义键值对容器，然后将 srcFieldMap 里的所有属性名称和属性值 put 进去")
    private static OwnPairs private_buildPair(C<?> pairType, Map<String, Field> srcFieldMap, Object srcBean) {
        C<?> keyType = pairType.generic(0);
        if(keyType != null && !String.class.equals(keyType.getMainType())) {
            throw new ClassCastException("JavaBean 对象转换为 OwnPairs 自定义键值对容器时，" +
                    "OwnPairs 自定义键值对容器的 key 的泛型必须是字符串");
        }
        Class<?> mainType = pairType.getMainType();
        int argCount = pairType.argCount();
        OwnPairs result;
        if(argCount == 0) {
            result = private_newNotArgOwnPairs(mainType, srcFieldMap.size());
        }
        else {
            Constructor<?> constructor = getConstructor(pairType);
            Object[] argValues = private_getArgValuesByBean(pairType, srcFieldMap, srcBean, constructor, argCount);
            result = (OwnPairs) buildObject(constructor, argValues);
        }
        C<?> valueType = pairType.generic(1);
        for (Map.Entry<String, Field> e : srcFieldMap.entrySet()) {
            Object value = getFieldValue(srcBean, e.getValue());
            Object realValue = toRealValue(value, valueType);
            result.put(e.getKey(), realValue);
        }
        return result;
    }

    @Note("判断不同类型的自定义键值对容器，分别构造它们的实例")
    private static OwnPairs private_newNotArgOwnPairs(Class<?> pairType, int size) {
        if(OwnPairs.class.equals(pairType) || AbsOwnPair.class.equals(pairType) || OwnMap.class.equals(pairType)) {
            return new OwnMap<>(MapEnum.calcInitSize(size));
        }
        if(OwnPair.class.equals(pairType)) {
            return new OwnPair(MapEnum.calcInitSize(size));
        }
        if(JsonPair.class.equals(pairType)) {
            return new JsonPair(-1, "");
        }
        return (OwnPairs) buildObject(pairType);
    }


    @Note("对拷贝内容后的 target 容器，对一些需要排除的 key 做 remove 操作")
    private static void private_containerExcludesOperation(Object target, String[] excludePropertyNames) {
        if(target instanceof Map) {
            Map map = (Map) target;
            for (String key : excludePropertyNames) map.remove(key);
            return;
        }
        if(target instanceof OwnPairs) {
            OwnPairs pairs = (OwnPairs) target;
            for (String key : excludePropertyNames) pairs.remove(key);
        }
    }


    @Note("对拷贝内容后的 target 容器，对一些需要排除的 key 做 remove 操作")
    private static void private_containerExcludesOperation(Object target, Iterable<String> excludePropertyNames) {
        if(target instanceof OwnPairs) {
            OwnPairs pairs = (OwnPairs) target;
            for (String key : excludePropertyNames) pairs.remove(key);
            return;
        }
        if(target instanceof Map) {
            Map map = (Map) target;
            for (String key : excludePropertyNames) map.remove(key);
        }
    }


    @Note("容器类内容拷贝的逻辑操作")
    private static boolean private_containerCopy(Object source, Object target) {
        //源是 Map 集合
        if(source instanceof Map) {
            Map src = (Map) source;
            if(target instanceof Map) {
                ((Map) target).putAll(src);
                return true;
            }
            if(target instanceof OwnPairs) {
                ((OwnPairs) target).putAll(src);
                return true;
            }
            Map<String, Field> fieldMap = allFields(target.getClass());
            for (Map.Entry<String, Field> e : fieldMap.entrySet()) {
                Object v = src.get(e.getKey());
                Field field = e.getValue();
                Object realValue = toRealValue(v, C.getC(field.getType()));
                setFieldValue(target, field, realValue);
            }
            return true;
        }
        //源是自定义键值对集合
        if(source instanceof OwnPairs) {
            OwnPairs src = (OwnPairs) source;
            if(target instanceof OwnPairs) {
                ((OwnPairs) target).putAll(src);
                return true;
            }
            if(target instanceof Map) {
                Map tar = (Map) target;
                for (Object o : src.entrySet()) {
                    Map.Entry e = (Map.Entry) o;
                    tar.put(e.getKey(), e.getValue());
                }
                return true;
            }
            Map<String, Field> fieldMap = allFields(target.getClass());
            for (Map.Entry<String, Field> e : fieldMap.entrySet()) {
                Field field = e.getValue();
                Object v = src.get(e.getKey());
                Object realValue = toRealValue(v, C.getC(field.getType()));
                setFieldValue(target, field, realValue);
            }
            return true;
        }
        //源是 Collection 集合
        if(source instanceof Collection) {
            Collection src = (Collection) source;
            if(target instanceof Collection) {
                ((Collection) target).addAll(src);
                return true;
            }
            if(target instanceof OwnRows) {
                ((OwnRows) target).addAll(src);
                return true;
            }
            Class<?> tarClass = target.getClass();
            if(tarClass.isArray()) {
                int length = Array.getLength(target);
                Class<?> componentType = tarClass.getComponentType();
                int i = 0;
                for (Object o : src) {
                    if(i == length) break;
                    Array.set(target, i, toRealValue(o, C.getC(componentType)));
                    i++;
                }
                return true;
            }
            throw new InvalidOperationException("无法将 java.util.Collection 的内容" +
                    "拷贝至 【" + tarClass.getName() + "】 中");
        }
        //源是自定义集合
        if(source instanceof OwnRows) {
            OwnRows src = (OwnRows) source;
            if(target instanceof OwnRows) {
                ((OwnRows) target).addAll(src);
                return true;
            }
            if(target instanceof Collection) {
                Collection tar = (Collection) target;
                for (Object o : src) {
                    tar.add(o);
                }
                return true;
            }
            Class<?> tarClass = target.getClass();
            if(tarClass.isArray()) {
                int i = 0;
                int length = Array.getLength(target);
                Class<?> componentType = tarClass.getComponentType();
                for (Object o : src) {
                    if(i == length) break;
                    Array.set(target, i, toRealValue(o, C.getC(componentType)));
                    i++;
                }
                return true;
            }
            throw new InvalidOperationException("无法将 com.tools.common.container.OwnRows 的内容" +
                    "拷贝至 【" + tarClass.getName() + "】 中");
        }
        //源是数组
        Class<?> srcClass = source.getClass();
        if(srcClass.isArray()) {
            if(target.getClass().isArray()) {
                RowKit.copyTo(source, target);
                return true;
            }
            int length = Array.getLength(source);
            if(target instanceof Collection) {
                Collection cs = (Collection) source;
                for (int i = 0; i < length; i++) {
                    cs.add(Array.get(source, i));
                }
                return true;
            }
            if(target instanceof OwnRows) {
                OwnRows row = (OwnRows) source;
                for (int i = 0; i < length; i++) {
                    row.add(Array.get(source, i));
                }
                return true;
            }
            throw new InvalidOperationException("无法将 【" + srcClass.getComponentType().getName() + "】 数组的内容" +
                    "拷贝至 【" + target.getClass().getName() + "】 中");
        }
        return false;
    }


    @Note("JavaBean 对象之间的拷贝属性操作，根据属性名称进行拷贝赋值")
    private static void private_beanCopy(Map<String, Field> sourceMap, Map<String, Field> targetMap, Object source, Object target) {
        for (Map.Entry<String, Field> e : targetMap.entrySet()) {
            Field sourceField = sourceMap.get(e.getKey());
            if(sourceField == null) {
                continue;
            }
            Field targetField = e.getValue();
            Object sourceValue = getFieldValue(source, sourceField);
            Object targetValue = toRealValue(sourceValue, C.getC(targetField.getType()));
            setFieldValue(target, targetField, targetValue);
        }
    }


    /* ************************************************************************************************************
     *
     *
     *          其他操作
     *
     * ************************************************************************************************************
     * */

    /**
     * @param obj 目标对象
     * @return 若对象是容器或者迭代器、字符串则返回其长度，否则返回 obj 的属性个数
     * */
    @Note("若对象是容器或者迭代器、字符串则返回其长度，否则返回 obj 的属性个数")
    public static int getLength(Object obj) {
        if(obj == null) return 0;
        if(obj instanceof CharSequence) return ((CharSequence) obj).length();
        if(obj instanceof Collection) return ((Collection<?>) obj).size();
        if(obj instanceof Map) return ((Map<?,?>) obj).size();
        if(obj.getClass().isArray()) return Array.getLength(obj);
        if(obj instanceof OwnRows) return ((OwnRows<?>) obj).size();
        if(obj instanceof OwnPairs) return ((OwnPairs<?,?>) obj).size();
        if(obj instanceof Iterable) {
            int length = 0;
            for (Object o : (Iterable<?>) obj) {
                length++;
                o = null;
            }
            return length;
        }
        return allFields(obj.getClass()).size();
    }


    public static boolean isNull(Object obj) {
        return obj == null;
    }

    public static boolean isAllNull(Object... objs) {
        if(objs == null || objs.length == 0) return false;
        for (Object o : objs) if(o != null) return false;
        return true;
    }

    public static boolean isAllNull(Collection objs) {
        if(objs == null || objs.isEmpty()) return false;
        for (Object o : objs) if(o != null) return false;
        return true;
    }

    public static boolean isAllNull(OwnRows objs) {
        if(objs == null || objs.isEmpty()) return false;
        for (Object o : objs) if(o != null) return false;
        return true;
    }

    public static boolean isAllNull(Iterable objs) {
        if(objs == null) return false;
        Iterator iterator = objs.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext()) if(iterator.next() != null) return false;
        return true;
    }

    public static boolean isAnyNull(Object... objs) {
        if(objs == null || objs.length == 0) return false;
        for (Object o : objs) if(o == null) return true;
        return false;
    }

    public static boolean isAnyNull(Collection objs) {
        if(objs == null || objs.isEmpty()) return false;
        for (Object o : objs) if(o == null) return true;
        return false;
    }

    public static boolean isAnyNull(OwnRows objs) {
        if(objs == null || objs.isEmpty()) return false;
        for (Object o : objs) if(o == null) return true;
        return false;
    }

    public static boolean isAnyNull(Iterable objs) {
        if(objs == null) return false;
        Iterator iterator = objs.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext()) if(iterator.next() == null) return true;
        return false;
    }



    public static boolean notNull(Object obj) {
        return obj != null;
    }

    public static boolean notAllNull(Object... objs) {
        if(objs == null || objs.length == 0) return false;
        for (Object o : objs) if(o == null) return false;
        return true;
    }

    public static boolean notAllNull(Collection objs) {
        if(objs == null || objs.isEmpty()) return false;
        for (Object o : objs) if(o == null) return false;
        return true;
    }

    public static boolean notAllNull(OwnRows objs) {
        if(objs == null || objs.isEmpty()) return false;
        for (Object o : objs) if(o == null) return false;
        return true;
    }

    public static boolean notAllNull(Iterable objs) {
        if(objs == null) return false;
        Iterator iterator = objs.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext()) if(iterator.next() == null) return false;
        return true;
    }

    public static boolean notAnyNull(Object... objs) {
        if(objs == null || objs.length == 0) return false;
        for (Object o : objs) if(o != null) return true;
        return false;
    }

    public static boolean notAnyNull(Collection objs) {
        if(objs == null || objs.isEmpty()) return false;
        for (Object o : objs) if(o != null) return true;
        return false;
    }

    public static boolean notAnyNull(OwnRows objs) {
        if(objs == null || objs.isEmpty()) return false;
        for (Object o : objs) if(o != null) return true;
        return false;
    }

    public static boolean notAnyNull(Iterable objs) {
        if(objs == null) return false;
        Iterator iterator = objs.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext()) if(iterator.next() != null) return true;
        return false;
    }


    public static boolean isEmpty(Object obj) {
        if(obj == null) return true;
        if(obj instanceof CharSequence) return ((String) obj).isEmpty();
        if(obj instanceof Collection) return ((Collection<?>) obj).isEmpty();
        if(obj instanceof OwnRows) return ((OwnRows<?>) obj).isEmpty();
        if(obj instanceof Map) return ((Map<?, ?>) obj).isEmpty();
        if(obj instanceof OwnPairs) return ((OwnPairs<?, ?>) obj).isEmpty();
        if(obj.getClass().isArray()) return Array.getLength(obj) == 0;
        if(obj instanceof Optional) return ((Optional<?>) obj).isPresent();
        return allFields(obj.getClass()).isEmpty();
    }


    public static boolean isAllEmpty(Object... objs) {
        if(objs == null || objs.length == 0) return false;
        for (Object o : objs) if(notEmpty(o)) return false;
        return true;
    }

    public static boolean isAllEmpty(Collection objs) {
        if(objs == null || objs.isEmpty()) return false;
        for (Object o : objs) if(notEmpty(o)) return false;
        return true;
    }

    public static boolean isAllEmpty(OwnRows objs) {
        if(objs == null || objs.isEmpty()) return false;
        for (Object o : objs) if(notEmpty(o)) return false;
        return true;
    }

    public static boolean isAllEmpty(Iterable objs) {
        if(objs == null) return false;
        Iterator iterator = objs.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext()) if(notEmpty(iterator.next())) return false;
        return true;
    }

    public static boolean isAnyEmpty(Object... objs) {
        if(objs == null || objs.length == 0) return false;
        for (Object o : objs) if(isEmpty(o)) return true;
        return false;
    }

    public static boolean isAnyEmpty(Collection objs) {
        if(objs == null || objs.isEmpty()) return false;
        for (Object o : objs) if(isEmpty(o)) return true;
        return false;
    }

    public static boolean isAnyEmpty(OwnRows objs) {
        if(objs == null || objs.isEmpty()) return false;
        for (Object o : objs) if(isEmpty(o)) return true;
        return false;
    }

    public static boolean isAnyEmpty(Iterable objs) {
        if(objs == null) return false;
        Iterator iterator = objs.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext()) if(isEmpty(iterator.next())) return true;
        return false;
    }

    public static boolean notEmpty(Object obj) {
        if(obj == null) return false;
        if(obj instanceof CharSequence) return !((String) obj).isEmpty();
        if(obj instanceof Collection) return !((Collection<?>) obj).isEmpty();
        if(obj instanceof OwnRows) return !((OwnRows<?>) obj).isEmpty();
        if(obj instanceof Map) return !((Map<?, ?>) obj).isEmpty();
        if(obj instanceof OwnPairs) return !((OwnPairs<?, ?>) obj).isEmpty();
        if(obj.getClass().isArray()) return Array.getLength(obj) != 0;
        if(obj instanceof Optional) return !((Optional<?>) obj).isPresent();
        return !allFields(obj.getClass()).isEmpty();
    }


    public static boolean notAllEmpty(Object... objs) {
        if(objs == null || objs.length == 0) return false;
        for (Object o : objs) if(isEmpty(o)) return false;
        return true;
    }

    public static boolean notAllEmpty(Collection objs) {
        if(objs == null || objs.isEmpty()) return false;
        for (Object o : objs) if(isEmpty(o)) return false;
        return true;
    }

    public static boolean notAllEmpty(OwnRows objs) {
        if(objs == null || objs.isEmpty()) return false;
        for (Object o : objs) if(isEmpty(o)) return false;
        return true;
    }

    public static boolean notAllEmpty(Iterable objs) {
        if(objs == null) return false;
        Iterator iterator = objs.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext()) if(isEmpty(iterator.next())) return false;
        return true;
    }

    public static boolean notAnyEmpty(Object... objs) {
        if(objs == null || objs.length == 0) return false;
        for (Object o : objs) if(notEmpty(o)) return true;
        return false;
    }

    public static boolean notAnyEmpty(Collection objs) {
        if(objs == null || objs.isEmpty()) return false;
        for (Object o : objs) if(notEmpty(o)) return true;
        return false;
    }

    public static boolean notAnyEmpty(OwnRows objs) {
        if(objs == null || objs.isEmpty()) return false;
        for (Object o : objs) if(notEmpty(o)) return true;
        return false;
    }

    public static boolean notAnyEmpty(Iterable objs) {
        if(objs == null) return false;
        Iterator iterator = objs.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext()) if(notEmpty(iterator.next())) return true;
        return false;
    }


    public static boolean equals(Object source, Object target) {
        return Objects.equals(source, target);
    }

    public static boolean equalsAll(Object source, Object... targets) {
        if(targets == null || targets.length == 0) return false;
        for (Object o : targets) if(!Objects.equals(source, o)) return false;
        return true;
    }

    public static boolean equalsAll(Object source, Collection<?> targets) {
        if(targets == null || targets.isEmpty()) return false;
        for (Object o : targets) if(!Objects.equals(source, o)) return false;
        return true;
    }

    public static boolean equalsAll(Object source, OwnRows<?> targets) {
        if(targets == null || targets.isEmpty()) return false;
        for (Object o : targets) if(!Objects.equals(source, o)) return false;
        return true;
    }

    public static boolean equalsAll(Object source, Iterable<?> targets) {
        if(targets == null) return false;
        Iterator<?> iterator = targets.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext())  if(!Objects.equals(source, iterator.next())) return false;
        return true;
    }

    public static boolean equalsAny(Object source, Object... targets) {
        if(targets == null || targets.length == 0) return false;
        for (Object o : targets) if(Objects.equals(source, o)) return true;
        return false;
    }

    public static boolean equalsAny(Object source, Collection<?> targets) {
        if(targets == null || targets.isEmpty()) return false;
        for (Object o : targets) if(Objects.equals(source, o)) return true;
        return false;
    }

    public static boolean equalsAny(Object source, OwnRows<?> targets) {
        if(targets == null || targets.isEmpty()) return false;
        for (Object o : targets) if(Objects.equals(source, o)) return true;
        return false;
    }

    public static boolean equalsAny(Object source, Iterable<?> targets) {
        if(targets == null) return false;
        Iterator<?> iterator = targets.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext())  if(Objects.equals(source, iterator.next())) return true;
        return false;
    }
}
